package be.kdg.bombermanunlimited.server.objects.finalclasses;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import be.kdg.bombermanunlimited.client.remote.interfaces.IGameListener;
import be.kdg.bombermanunlimited.server.objects.interfaces.IPlayer;
import be.kdg.bombermanunlimited.server.remote.interfaces.IServerGameListener;
/**
 * locale speler. bevat naam, bombrange en plaats informatie.
 * 2 extra velden server en client zijn een soort van listenere.
 * server wordt gebruikt voor communicatie naar het draaiende serverGame.
 * client wordt opgeroepen door de serverGame om via deze interface de client te bereiken.
 * @author pieter
 *
 */
public class Player extends UnicastRemoteObject implements IPlayer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5102749572316827085L;
	private String name;
	private int bombRange;
	private int row, column;
	IServerGameListener server;
	IGameListener client;
	boolean dead;

	public Player(String name, int row, int collumn,
			IGameListener clientGameListener,
			IServerGameListener serverGameListener) throws RemoteException {
		this.name = name;
		this.row = row;
		this.column = collumn;
		this.client = clientGameListener;
		this.bombRange = 3;
		this.server = serverGameListener;
		this.dead = false;

	}

	public IGameListener getClient() throws RemoteException {
		return client;
	}

	public void dropBomb() throws RemoteException {
		if (!dead) {
			server.addBomb(this.row, this.column, this.bombRange);
		}
	}

	public int getBombRange() throws RemoteException {
		return bombRange;
	}

	public void setBombRange(int bombRange) throws RemoteException {
		this.bombRange = bombRange;
		server.Update(this);
	}

	public void increaseBombRange() throws RemoteException {
		if (!dead) {
			this.bombRange = this.getBombRange() + 1;
			server.Update(this);
		}
	}

	public void setName(String name) throws RemoteException {
		this.name = name;
	}

	public String getName() throws RemoteException {
		// TODO Auto-generated method stub
		return this.name;
	}

	public int getRow() throws RemoteException {
		// TODO Auto-generated method stub
		return row;
	}

	public int getColumn() throws RemoteException {
		return column;
	}

	public byte setPosition(int row, int column) throws RemoteException {
		if (!dead) {
			this.row = row;
			this.column = column;
			server.Update(this);
			return getWalkableDirectionsLocalCall();
		}
		
		return 0;
	}

	public byte incRow() throws RemoteException {
		if (!dead) {
			row++;
			server.Update(this);
			return getWalkableDirectionsLocalCall();
		}
		
		return 0;
	}

	public byte decRow() throws RemoteException {
		if (!dead) {
			row--;
			server.Update(this);
			return getWalkableDirectionsLocalCall();
		}
		
		return 0;
	}

	public byte incColumn() throws RemoteException {
		if (!dead) {
			column++;
			server.Update(this);
			
			return getWalkableDirectionsLocalCall();
		}
		
		return 0;
	}

	public byte decColumn() throws RemoteException {
		if (!dead) {
			column--;
			server.Update(this);
			return getWalkableDirectionsLocalCall();
		}
		
		return 0;
	}

	public byte setRow(int row) throws RemoteException {
		if (!dead) {
			this.row = row;
			server.Update(this);
			return getWalkableDirectionsLocalCall();
		}
		
		return 0;
	}

	public byte setColumn(int column) throws RemoteException {
		if (!dead) {
			this.column = column;
			server.Update(this);
			return getWalkableDirectionsLocalCall();
		}
		
		return 0;
	}

	public void setListener(IServerGameListener listener) {
		this.server = listener;
	}

	public boolean isCanGoUp() {
		return server.isWalkable(row - 1, column);
	}

	public boolean isCanGoDown() {
		return server.isWalkable(row + 1, column);
	}

	public boolean isCanGoLeft() {
		return server.isWalkable(row, column - 1);
	}

	public boolean isCanGoRight() {
		return server.isWalkable(row, column + 1);
	}

	public byte getWalkableDirections() {
		return getWalkableDirectionsLocalCall();
	}

	public byte getWalkableDirectionsLocalCall() {
		byte directions = 0;

		if (isCanGoDown()) {
			directions |= IPlayer.WALK_DOWN;
		}
		if (isCanGoLeft()) {
			directions |= IPlayer.WALK_LEFT;
		}
		if (isCanGoRight()) {
			directions |= IPlayer.WALK_RIGHT;
		}
		if (isCanGoUp()) {
			directions |= IPlayer.WALK_UP;
		}

		return directions;
	}

	public void setDead() throws RemoteException {
		dead = true;
	}

}
